package gui;

import javax.swing.*;
import java.awt.*;

/**
 * Created with IntelliJ IDEA.
 * User: Eliseo
 * Date: 06.11.13
 * Time: 22:31
 */
public class PanelPong extends JPanel implements Runnable {


    private static int ANZAHL_TRENNLINIEN = 5;
    private static int ABSTAND_OBENUNTEN = 10;
    private static int ABSTAND_ZWISCHEN_TRENNLINIE = 20;

    private JFrame frame;
    private Ball mBall;
    private SchlaegerRechts mSchlaegerRechts;
    private SchlaegerLinks mSchlaegerLinks;
    private long last;
    private long delta;
    private long fps;
    private int trefferZahler;

    public static void main(String[] args) {
        new PanelPong();
    }

    public Ball getBall() {
        return mBall;
    }

    public PanelPong() {

        this.setPreferredSize(new Dimension(600, 600));
        //Panelsettings
        setBackground(Color.black);

        frame = new JFrame("PONG");
        frame.setLocation(100, 100);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(this);
        frame.pack();
        frame.setVisible(true);

        doInitializations();

        frame.addKeyListener(mSchlaegerRechts);
        frame.addKeyListener(mSchlaegerLinks);

        Thread th = new Thread(this);
        th.start();
    }

    private void doInitializations() {
        mBall = new Ball();
        mSchlaegerRechts = new SchlaegerRechts(getWidth(), getHeight());
        mSchlaegerLinks = new SchlaegerLinks(getWidth(), getHeight());
        last = System.nanoTime();
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        g.setColor(Color.red);
        g.drawString("FPS: " + Long.toString(fps), 20, 10);

        drawLine(g);
        mSchlaegerRechts.drawSchlaeger(g, getWidth());
        mSchlaegerLinks.drawSchlaeger(g);
        mBall.move(g, getWidth(), getHeight());
    }

    @Override
    public void run() {
        while (frame.isVisible()) {

            computeDelta();

            checkKeys();
            doLogic();
            repaint();

            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                //nichts
            }
        }

    }

    private void doLogic() {


        /**
         *  Erkennt wenn der Ball den rechten Schläger  berührt. Die Flugrichtung des
         *  Balles wird dann umgedreht, und der Ball wird über -1 wieder vor den Schläger
         *  positioniert
         */
        if (mBall.intersects(mSchlaegerRechts.getX(), mSchlaegerRechts.getY(), 10, 100)) {   //todo beide Methode rufen die selbe Funktion auf, daher später hier ein oder machen
            if (verbotenerBereichSchläger(mSchlaegerRechts)) {
                System.out.println("TrefferRechts");

                mBall.wechsleFlugRichtung();

            } else {
                mBall.resetBall();
            }
        }


       /**
         * Erkennt wenn der Ball den linken Schläger berührt. Die Flugrichtung
         * wird dann gewechselt. Mit + 1 wird der Ball wieder kurz vor der Berührung wieder
         * positioniert
         */
        if (mBall.intersects(mSchlaegerLinks.getX(), mSchlaegerLinks.getY(), 10, 100)) {
            if (verbotenerBereichSchläger(mSchlaegerLinks)) {
                System.out.println("TrefferLinks");
                mBall.wechsleFlugRichtung();
            } else {
                mBall.resetBall();
            }

        }

          }

    /**
     * Dieser Methode wird jeweilig der rechte oder linke Schläger übergeben. Daraufhin wird überprüft ob der Ball in einem
     * Bereich ist der nicht mehr schön zurück prallen würde. Daher wird der Ball geresetet.
     * @param schlaeger
     * @return
     */
    private boolean verbotenerBereichSchläger(Schlaeger schlaeger) {
        if (mBall.getY() > (schlaeger.getY() + schlaeger.HOEHE_DES_SCHLAEGERS - (5* schlaeger.HOEHE_DES_SCHLAEGERS/100)) || (mBall.getY()+15) < (schlaeger.getY() + 5)) {
            return false;
        } else {
            return true;
        }
    }

    private void computeDelta() {
        delta = System.nanoTime() - last;
        last = System.nanoTime();
        fps = ((long) 1e9) / delta;
    }


    public Schlaeger getmSchlaegerRechts() {
        return mSchlaegerRechts;
    }

    public Schlaeger getmSchlaegerLinks() {
        return mSchlaegerLinks;
    }

    private void checkKeys() {
        if (mSchlaegerRechts.isUpRIGHT()) {
            mSchlaegerRechts.moveVerticalUP();
        }
        if (mSchlaegerRechts.isDownRIGHT()) {
            mSchlaegerRechts.moveVerticalDOWN();
        }
        if (mSchlaegerLinks.isUpLEFT()) {
            mSchlaegerLinks.moveVerticalUP();
        }
        if (mSchlaegerLinks.isDownLEFT()) {
            mSchlaegerLinks.moveVerticalDOWN();
        }
    }

    /**
     * Diese Methode sollte die Linie zeichnen welche die 2 Spielhälften
     * voneinander trennt. Die Linie soll sich aber dem Fenster anpassen
     */
    private void drawLine(Graphics g) {
        g.setColor(Color.white);
        int abstandZumOberenRand = ABSTAND_OBENUNTEN;
        int strichlaenge = berechneStrichlaenge();

        for (int i = 0; i < ANZAHL_TRENNLINIEN; i++) {
            g.fillRect(((getWidth() / 2) - 5), abstandZumOberenRand, 10, strichlaenge);
            abstandZumOberenRand += berechneStrichlaenge() + ABSTAND_ZWISCHEN_TRENNLINIE;
        }
    }

    /**
     * Diese Methode rechent aus wie lang ein Strich sein darf.
     * Dazu wird der Abstand von oben und unten und der Abstand zwischen
     * denn Trennlininen subtrahiert
     *
     * @return
     */
    private int berechneStrichlaenge() {
        int länge;
        int verfügbarerPlatz = getHeight() - (ABSTAND_OBENUNTEN * 2);
        verfügbarerPlatz = verfügbarerPlatz - (ABSTAND_ZWISCHEN_TRENNLINIE * (ANZAHL_TRENNLINIEN - 1));

        länge = verfügbarerPlatz / ANZAHL_TRENNLINIEN;
        return länge;
    }
}